import sys
import threading
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

# 帮我们直接运行此文件时，可以加载到上级目录的ui包
# 注意，需要放在导入ui包的前面
sys.path.append("../")

from ui.Ui_ble_control_widget import Ui_BleControlWidget
from drivers.driver_bluetooth import *
from common.utils import *
from common.hex_util import *

class BleControlWidget(QWidget):
    # 信号定义
    devices_signal = pyqtSignal(list)
    recv_data_signal = pyqtSignal(bytes)

    def __init__(self, parent=None):
        super().__init__(parent)
        # 实例化ui模块对象，调用setupUi()方法
        self.ui = Ui_BleControlWidget()
        self.ui.setupUi(self)
        
        # 实例属性
        self.devices = [] # 设备列表
        self.bdt: BluetoothDataTransfer = None
        
        
        # 初始化UI界面
        self.init_ui()
    
    def devices_signal_slot(self, devices):
        print("设备列表自定义信号槽函数")
        self.devices = devices
        self.ui.comboBox.clear()
        for device in devices:
            self.ui.comboBox.addItem(device[1])
            
        # 展开下拉框
        self.ui.comboBox.showPopup()

    def refresh_devices(self):
        print("刷新设备列表线程处理函数")
        print("=========================================开始扫描")
        devices = BluetoothDataTransfer.scan_devices()
        # for device in devices:
        #     print(device)
        # print(devices)
        # print([device[1] for device in devices])
        # 信号发射
        self.devices_signal.emit(devices)
        print("=========================================结束扫描")
        
    def refreshBtnSlot(self):
        print("扫描按钮槽函数")
        # 创建线程，设置为守护线程
        t = threading.Thread(target=self.refresh_devices, daemon=True)
        t.start()
    
    def recv_data_signal_slot(self, bytes_arr):
        print("接收数据自定义信号槽函数")
        msg = decode_data(bytes_arr)
        print(msg)    

    def connect_device(self, device):
        print("连接设备线程处理函数")
        addr, name = device
        self.bdt = BluetoothDataTransfer(addr, name, 1)  # 替换为目标设备的蓝牙地址和端口号
        if not self.bdt.connect():
            print("连接失败")
            # 弹出警告框
            QMessageBox.warning(self, "警告", "连接失败")
            return
        
        print("连接成功") 
        
        try:
            print("开始接收数据")
            while True:
                bytes_arr = self.bdt.receive_data()
                if bytes_arr:
                    # 信号发射
                    self.recv_data_signal.emit(bytes_arr)
                    # msg = decode_data(bytes_arr)
                    # print(msg)
                else:
                    # 当主动调用disconnect或设备被动断开时
                    # bytes_arr会收到长度为零bytes
                    break
        except Exception as e:
            print(e)

    def connectBtnSlot(self):
        print("连接按钮槽函数")
        
        # 读取cb_devices中选中的设备
        device_index = self.ui.comboBox.currentIndex()
        if device_index == -1:
            print("未选择任何设备，请重新选择")
            # 弹出警告框
            QMessageBox.warning(self, "警告", "未选择任何设备，请重新选择")
            return
        device = self.devices[device_index]
        print("连接设备:", device)
        
        # 启动子线程，设置为守护线程
        t = threading.Thread(target=self.connect_device, args=(device,), daemon=True)
        t.start()

    def init_ui(self):
        # 按钮信号和槽绑定
        self.ui.refreshBtn.clicked.connect(self.refreshBtnSlot) # 刷新按钮
        self.ui.connectBtn.clicked.connect(self.connectBtnSlot) # 连接按钮
        
        # 自定义信号绑定
        self.devices_signal.connect(self.devices_signal_slot)
        self.recv_data_signal.connect(self.recv_data_signal_slot)

        
if __name__ == "__main__":
    app = QApplication(sys.argv)

    w = BleControlWidget()
    w.show()

    sys.exit(app.exec_())
